import 'dart:io';
import 'dart:typed_data';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'BaseModel.dart';

// 媒体类型
enum MediaType {
  all,
  image,
  video,
}

// 相册页logic
class PhotoAlbumLogic extends BaseModel {
  PhotoAlbumLogic();

  // 正在加载
  bool isLoading = true;

  // 媒体类型
  MediaType get currentMediaType => _currentMediaType;
  set currentMediaType(MediaType value) {
    if (_currentMediaType != value) {
      _currentMediaType = value;
      notifyListeners();  // 发出通知
    }
  }
  MediaType _currentMediaType = MediaType.all;

  // 日期文件数据
  List<DateFile> get dateFileList {
    switch (currentMediaType) {
      case MediaType.all:
        return List.unmodifiable(_dateFileList);
      case MediaType.image:
        return List.unmodifiable(_dateFileImageList);
      case MediaType.video:
        return List.unmodifiable(_dateFileVideoList);
      default:
        return List.unmodifiable(_dateFileList);
    }
  }

  List<DateFile> _dateFileList = [];
  List<DateFile> _dateFileImageList = [];
  List<DateFile> _dateFileVideoList = [];

  int _currentPage = 0;      // 当前页码
  final int _pageSize = 100; // 每页加载的数量

  final String tag = "~~~ PhotoAlbumLogic, ";

  init() {
    getMedia();
  }

  // 获取媒体资源
  Future<void> getMedia() async {

    // // 已经在相册外部做处理, 故隐藏掉. (测试发现鸿蒙3中已经给了权限, 但这里isAuth还是false)
    // final PermissionState ps = await PhotoManager.requestPermissionExtend();
    // if (!ps.isAuth) {
    //   print(tag + "!!! getMedia 没有授权");
    //   return;
    // }

    // 获取相册列表
    List<AssetPathEntity> albums = await PhotoManager.getAssetPathList();
    if (albums.isEmpty) {
      print(tag + "!!! getMedia 相册为空");
      return;
    }

    // 查找指定相册名
    var albumName = "flutterTest";
    AssetPathEntity? album;
    try {
      album = albums.firstWhere((element) => element.name == albumName);
    } catch (e) {
      print("!!! getMedia 未找到相册: $albumName");
    }
    album ??= albums[0];  // 没找到就默认用第一个

    int totalAssets = await album.assetCountAsync;
    int start = _currentPage * _pageSize;
    int end = start + _pageSize;
    if (start >= totalAssets) {
      print(tag + "!!! All assets are loaded.");
      return;
    }

    // 获取指定相册中的所有媒体文件
    List<AssetEntity> assets = await album.getAssetListRange(start: start, end: end);
    _currentPage++;

    // 使用 Map 来将媒体文件按日期分组
    Map<DateTime, List<CustomFileInfo>> dateFileMap = {};

    // 异步处理每一个媒体文件
    List<Future> tasks = [];
    for (var media in assets) {
      tasks.add(_processMedia(media, dateFileMap));
    }
    // 等待所有媒体文件处理完成
    await Future.wait(tasks);

    // 将分组后的数据保存到 dateFileList 中
    List<DateFile> newEntries = dateFileMap.entries.map((entry) => DateFile(creationTime: entry.key, dateMediaInfoList: entry.value)).toList();
    _addToDateFiles(newEntries);

    isLoading = false;
    notifyListeners();
  }

  // 处理媒体文件
  Future<void> _processMedia(AssetEntity media, Map<DateTime, List<CustomFileInfo>> dateFileMap) async {
    File? mediaFile = await media.file;
    if (mediaFile == null) {
      print(tag + "!!! _processMedia, mediaFile == null");
      return;
    }

    print(tag + "获取缩略图, creationTime: ${media.createDateTime}, type: ${media.type}, path: ${mediaFile.path}");
    final thumbnailData = await media.thumbnailDataWithSize(ThumbnailSize(200, 200));
    if (thumbnailData == null) {
      print(tag + "!!! 获取缩略图失败, creationTime: ${media.createDateTime}, isVideo: ${AssetType.video}, path: ${mediaFile.path}");
      return;
    }
    CustomFileInfo fileInfo = CustomFileInfo(
      thumbnailData: thumbnailData,
      path: mediaFile.path,
      creationTime: media.createDateTime, // await _getFileCreationTime(mediaFile.path),
      isVideo: media.type == AssetType.video,
    );

    print(tag + "creationTime: ${fileInfo.creationTime}, isVideo: ${fileInfo.isVideo}, path: ${fileInfo.path}");

    // 将媒体文件按日期分组
    DateTime date = DateTime(fileInfo.creationTime.year, fileInfo.creationTime.month, fileInfo.creationTime.day);
    dateFileMap.putIfAbsent(date, () => []).add(fileInfo);
  }

  // 更新 dateFileList
  void _addToDateFiles(List<DateFile> newEntries) {

    // 遍历新条目，并适当地添加或合并到 dateFileList
    for (DateFile newEntry in newEntries) {
      // 尝试找到现有列表中日期相同的条目
      int existingIndex = _dateFileList.indexWhere((element) => element.creationTime == newEntry.creationTime);
      if (existingIndex != -1) {
        // 如果找到日期相同的条目，合并媒体信息列表
        _dateFileList[existingIndex].dateMediaInfoList.addAll(newEntry.dateMediaInfoList);
      } else {
        // 如果没有找到，直接添加新条目
        _dateFileList.add(newEntry);
      }
    }

    // 更新 dateFileImageList 和 dateFileVideoList
    _updateFilteredLists();
  }

  // 更新 dateFileImageList 和 dateFileVideoList
  void _updateFilteredLists() {
    _dateFileImageList.clear();
    _dateFileVideoList.clear();

    for (var dateFile in _dateFileList) {
      List<CustomFileInfo> imageList = dateFile.dateMediaInfoList.where((info) => !info.isVideo).toList();
      List<CustomFileInfo> videoList = dateFile.dateMediaInfoList.where((info) => info.isVideo).toList();

      if (imageList.isNotEmpty) {
        _dateFileImageList.add(DateFile(
          creationTime: dateFile.creationTime,
          dateMediaInfoList: imageList,
        ));
      }

      if (videoList.isNotEmpty) {
        _dateFileVideoList.add(DateFile(
          creationTime: dateFile.creationTime,
          dateMediaInfoList: videoList,
        ));
      }
    }
  }

  // 生成视频缩略图
  Future<String> _createVideoThumbnail(String videoPath) async {
    try {
      // 获取临时目录
      Directory tempDir = await getTemporaryDirectory();
      // 生成缩略图的唯一文件名
      String thumbFileName = "${DateTime.now().millisecondsSinceEpoch}.png";
      // 创建缩略图的完整路径
      String thumbPath = "${tempDir.path}/$thumbFileName";
      // 检查缩略图是否已存在
      bool thumbnailExists = await File(thumbPath).exists();
      if (!thumbnailExists) {
        print(tag + "createVideoThumbnail thumbPath:$thumbPath");
        // 生成视频缩略图并将其保存在临时目录中
        await VideoThumbnail.thumbnailFile(video: videoPath, thumbnailPath: thumbPath, imageFormat: ImageFormat.PNG, quality: 100);
      }
      return thumbPath;
    } catch (e) {
      print(tag + "视频缩略图生成失败 error:$e");
      return "";
    }
  }

  // 获取文件创建时间
  Future<DateTime> _getFileCreationTime(String filePath) async {
    try {
      File file = File(filePath);
      FileStat fileStat = await file.stat();
      return fileStat.changed;
    } catch (e) {
      print(tag + "!!! getFileCreationTime error:$e");
      return DateTime.now();
    }
  }
}

// 日期分组
class DateFile {
  final DateTime creationTime;
  final List<CustomFileInfo> dateMediaInfoList;

  DateFile({required this.creationTime, required this.dateMediaInfoList});
}

// 文件信息
class CustomFileInfo {
  final Uint8List thumbnailData;  // 缩略图数据
  final String path;              // 媒体文件路径
  final DateTime creationTime;    // 创建时间
  final bool isVideo;             // 是否视频

  CustomFileInfo({required this.thumbnailData, required this.path, required this.creationTime, required this.isVideo});

  String formattedDate() {
    return DateFormat('yyyy-MM-dd').format(creationTime);
  }
}